package com.xiaodeng.xdblogspringboot.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import com.xiaodeng.xdblogspringboot.exception.UserException;
import com.xiaodeng.xdblogspringboot.interceptors.AdminInterceptor;
import com.xiaodeng.xdblogspringboot.interceptors.LoginInterceptor;
import com.xiaodeng.xdblogspringboot.pojo.*;
import com.xiaodeng.xdblogspringboot.pojo.DTO.AdminDTO;
import com.xiaodeng.xdblogspringboot.pojo.DTO.UserDTO;
import com.xiaodeng.xdblogspringboot.service.AdminService;
import com.xiaodeng.xdblogspringboot.service.UserService;
import com.xiaodeng.xdblogspringboot.utils.ThreadLocalUtil;
import jakarta.validation.constraints.Pattern;
import org.hibernate.validator.constraints.URL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.xiaodeng.xdblogspringboot.constant.RedisConstants.*;

@RestController
@RequestMapping("/admin")
public class AdminController {
    @Autowired
    private AdminService adminService;
    @Autowired
    private UserService userService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 登录
     *
     * @param username 用户名
     * @param password 密码
     * @return result<字符串>
     */
    @PostMapping ("login")
    public Result<String> login(@Validated String username, String password) {
        String token = adminService.login(username, password);
        // 使用用户名作为键来存储 token
        String userKey = USER_TOKEN + username;
        // 检查是否已有 token
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        String oldToken = operations.get(userKey);
        if (oldToken != null) {
            // 使用 userKey 删除旧的 token
            stringRedisTemplate.delete(userKey);
        }
        // 存储新的 token
        operations.set(userKey, token, 4, TimeUnit.HOURS);
        return Result.success("登陆成功",token);
    }


    /**
     * 注册
     *
     * @param username         用户名
     * @param password         密码
     * @param verificationCode 验证码
     * @param email            电子邮件
     * @return 结果
     */
    @PostMapping("register")
    public Result register(@Pattern(regexp = "^[a-zA-Z0-9_.*]{6,16}$",message = "账号仅支持6到16位的数字、字母、‘_’、‘.’和‘*’！") String username,
                           @Pattern(regexp = "^[a-zA-Z0-9_.*]{6,16}$",message = "密码仅支持6到16位的数字、字母、‘_’、‘.’和‘*’！") String password,
                           @RequestParam String verificationCode, @RequestParam String email) {
        // 从 Redis 中获取验证码
        String redisKey = VERIFICATION_CODE + email;
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        String storedCode = operations.get(redisKey);
        System.out.println(storedCode);
        // 验证验证码
        if (storedCode == null || !storedCode.equals(verificationCode)) {
            return Result.error("验证码无效或已过期");
        }
        // 如果验证码有效，进行注册
        adminService.register(username,password,email);
        // 注册成功后，删除验证码
        stringRedisTemplate.delete(redisKey);
        return Result.success("注册成功");
    }

    /**
     * 登出
     *
     * @param token 令 牌
     * @return 结果
     */
    @AdminInterceptor.AdminIntercept
    @PostMapping("/logout")
    public Result logout(@RequestHeader("Authorization") String token) {
        // 从 Redis 中删除 token
        stringRedisTemplate.delete(token);
        return Result.success("登出成功");
    }

    /**
     * 删除
     *
     * @param id 身份证
     * @return 结果
     */
    @AdminInterceptor.AdminIntercept
    //  管理员注销
    @DeleteMapping("/delete")
    public Result delete(Integer id){
        adminService.delete(id);
        return Result.success("注销成功");
    }

    /**
     * 更新个人信息
     *
     * @param admin 管理
     * @return 结果
     */
    @AdminInterceptor.AdminIntercept
    //管理员修改信息
    @LoginInterceptor.GlobalJwtIntercept
    @PatchMapping  ("/update")
    public Result update(@Validated @RequestBody Admin admin){
        adminService.update(admin);
        return Result.success("修改成功");
    }

    /**
     * 更新头像
     *
     * @param avatarUrl 头像 URL
     * @return 结果
     */
    @AdminInterceptor.AdminIntercept
    //管理员用户头像
    @PatchMapping("/updateAvatar")
    public Result updateAvatar(@RequestParam @URL String avatarUrl){
        adminService.updateAvatar(avatarUrl);
        return Result.success();
    }

    /**
     * 更新 pwd
     *
     * @param adminDTO 管理员 DTO
     * @param token    令 牌
     * @return 结果
     */
    @AdminInterceptor.AdminIntercept
    //管理员修改密码
    @PatchMapping("/updatePwd")
    public Result updatePwd(@RequestBody @Validated AdminDTO adminDTO, @RequestHeader("Authorization") String token){
        Admin admin = BeanUtil.copyProperties(adminDTO,Admin.class);
        String newPwd = adminDTO.getNewPwd();
        adminService.updatePwd(newPwd,admin);
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        operations.getOperations().delete(token);
        return Result.success("修改成功");
    }

    /**
     * 管理员信息
     *
     * @return 结果<admin>
     */
    @AdminInterceptor.AdminIntercept
    @GetMapping("/adminInfo")
    public Result<Admin> adminInfo(){
        //根据用户名查询用户
        Map<String,Object> map = ThreadLocalUtil.get();
        String username =(String) map.get("username");
        Admin admin = adminService.findByUserName(username);
        return Result.success(admin);
    }


    /**
     * 发送验证码
     *
     * @param email 邮箱
     * @return 返回信息
     */
    @GetMapping("/verificationCode")
    public Result<Object> sendVerificationCode(@RequestParam @Validated String email) {
        // 生成六位数字验证码
        String verificationCode = RandomUtil.randomNumbers(6);
        // 发送验证码到用户邮箱
        userService.sendEmail(email, verificationCode);
        // 将验证码存储到 Redis，设置有效期为 5 分钟
        stringRedisTemplate.opsForValue().set(VERIFICATION_CODE + email, verificationCode, 5, TimeUnit.MINUTES);
        return Result.success("验证码发送成功！", null);
    }

    /**
     * 用户列表
     *
     * @param pageNum  页码
     * @param pageSize 页面大小
     * @param username 用户名
     * @param email    电子邮件
     * @return result<Page Bean < user>>
     */
    @AdminInterceptor.AdminIntercept
    @GetMapping("/userList")
    public Result<PageBean<User>> userList(
            Integer pageNum,
            Integer pageSize,
            @RequestParam(required = false) String username,
            @RequestParam(required = false) String email){
        PageBean<User> pb = adminService.userList(pageNum,pageSize,username,email);
        return Result.success(pb);
    }

    /**
     * 获取用户
     *
     * @param username 用户名
     * @return result<用户>
     */
    @AdminInterceptor.AdminIntercept
    @GetMapping("/getUser")
    public Result<User> getUser(String username){
        User user = userService.findByUserName(username);
        if (user == null){
            throw new UserException(501,"不存在该用户");
        }
        return Result.success(user);
    }

    /**
     * 添加用户
     *
     * @param user 用户
     * @return 结果
     */
    @AdminInterceptor.AdminIntercept
    @PostMapping("/addUser")
    public Result addUser(@Validated @RequestBody User user){
        adminService.addUser(user);
        return Result.success();
    }

    /**
     * 重置 用户pwd
     *
     * @param userDTO 用户 DTO
     * @return result<用户>
     */
    @AdminInterceptor.AdminIntercept
    //管理员重置用户密码
    @PatchMapping  ("/resetPwd")
    public Result<User> resetPwd(@Validated @RequestBody UserDTO userDTO){
        User user = BeanUtil.copyProperties(userDTO,User.class);
        String newPwd = "123456";
        adminService.resetPwd(newPwd,user);
        return Result.success("修改成功",user);
    }

    /**
     * 更新用户信息
     *
     * @param user 用户
     * @return result<用户>
     */
    @AdminInterceptor.AdminIntercept
    //  **更新用户信息**
    @PatchMapping  ("/updateUser")
    public Result<User> update(@Validated @RequestBody User user){
        User user1 =  adminService.updateUser(user);
        return Result.success("修改成功",user1);
    }

    /**
     * del 用户
     *
     * @param id 身份证
     * @return 结果
     */
    @AdminInterceptor.AdminIntercept
    @DeleteMapping("/delUser")
    public Result delUser(Integer id){
        userService.delete(id);
        return Result.success("删除成功");
    }






}
